CloudFormationがStep FunctionsをサポートしたのでServerless Frameworkから使ってみた
はじめに
こんにちは、中山です。
米国時間2017/02/10、CloudFormation(以下CFn)がStep Functionsをサポートしました。今回導入されたリソースは以下の2つです。プロパティに指定可能な値はドキュメントを参照してください。
- AWS::StepFunctions::Activity
- Activitiyの作成
- AWS::StepFunctions::StateMachine
- State Machineの作成
早速使ってみたので本エントリでご紹介させていただきます。単純に使うだけだとあまり面白くないのでServerless Frameworkからこの機能を利用してみます。なお、Serverless FrameworkとStep Functionsの連携はプラグインを利用することでも実現可能です。ご興味があれば以下のエントリを参照してください。
本エントリを執筆する上で検証に利用した主要なツールのバージョンは以下の通りです。バージョンによって結果が変更される可能性があるので、その点ご了承ください。
- Serverless Framework: 1.6.1
使ってみる
以下のファイルを用意してください。
serverless.yml
service: aws-python frameworkVersion: ">=1.6.0" custom: config: ${file(config.${opt:stage}.yml)} provider: name: aws runtime: python2.7 stage: ${opt:stage} region: ap-northeast-1 functions: hello: handler: handler.hello resources: ${file(resource.yml)}
Serverless Frameworkは resources
プロパティでCFnテンプレートを指定できます。 serverless.yml
に直接記述することも可能ですが、上記のように ${file(path/to/template.yml)}
の形で別ファイルから読み込むことも可能です。
resource.yml
--- AWSTemplateFormatVersion: "2010-09-09" Description: Step Functions Test Resources: InvokeLambdaRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Sid: StepFunctionsAssumeRolePolicy Effect: Allow Principal: Service: Fn::Join: [ ".", [ states, Ref: "AWS::Region", amazonaws, com ] ] Action: sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaRole TestStateMachine: Type: AWS::StepFunctions::StateMachine Properties: RoleArn: Fn::GetAtt: [ InvokeLambdaRole, Arn ] DefinitionString: |- { "StartAt": "HelloWorld", "States": { "HelloWorld": { "Type": "Task", "Resource": "arn:aws:lambda:${self:provider.region}:${self:custom.config.accountId}:function:${self:service}-${opt:stage}-hello", "End": true } } } Outputs: StateMachineArn: Value: Ref: TestStateMachine StateMachineName: Value: Fn::GetAtt: [ TestStateMachine, Name ]
CFnテンプレートの内容は単純です。 AWS::Iam::Role
リソースでState Machine用のIAM Roleを作成し、 AWS::StepFunctions::StateMachine
でState Machineを作成しています。
AWS::StepFunctions::StateMachine
リソースでは DefinitionString
プロパティでAmazon State Languageを記述できます。 Task
に指定している Resource
にはServerless FrameworkでデプロイしたLambda関数のARNを指定する必要がるのですが、今回は各種値(リージョンやAWSアカウントIDなど)にServerless Frameworkの強力な変数展開機能を利用しました。もし、CFn単体でState Machineを作成するのであれば、以下のようにFn::Sub組み込み関数を利用してLambda関数のARNを取得するとよいと思います。
TestStateMachine: Type: AWS::StepFunctions::StateMachine Properties: RoleArn: !GetAtt InvokeLambdaRole.Arn DefinitionString: !Sub |- { "StartAt": "HelloWorld", "States": { "HelloWorld": { "Type": "Task", "Resource": "${SomeLambdaFunc.Arn}", "End": true } } }
なお、残念ながらServerless Framework 1.6.1時点ではCFnの組み込み関数の短縮機能がサポートされていないようです。また、例えば AWSTemplateFormatVersion: "2010-09-09"
の日付部分を引用符で囲まないとエラーが出てしまいます。恐らくCFnではなくServerless Framework独自のバリデーションがテンプレート作成の前に働いているのかと推測しますが、この辺りもう少し改善してほしいですね。
スタックの作成は以下のコマンドで実行します。今回は説明を省略しましたが、利用しているLambda関数は sls create
で出力されるテンプレートをそのまま使っています。
$ sls deploy -v -s dev Serverless: Creating Stack... Serverless: Checking Stack create progress... <snip>
スタックが作成されたらState Machineの動作を確認してみます。
- State Machineが作成されたことを確認
$ aws stepfunctions list-state-machines { "stateMachines": [ { "creationDate": 1486760475.332, "stateMachineArn": "arn:aws:states:ap-northeast-1:************:stateMachine:TestStateMachine-4VMKMDOODSCT", "name": "TestStateMachine-4VMKMDOODSCT" } ] }
- State Machineの内容が意図したものになっていることを確認
$ aws stepfunctions describe-state-machine \ --state-machine-arn "$(aws stepfunctions list-state-machines \ --query 'stateMachines[?name==`TestStateMachine-4VMKMDOODSCT`].stateMachineArn' \ --output text)" { "status": "ACTIVE", "definition": "{\n \"StartAt\": \"HelloWorld\",\n \"States\": {\n \"HelloWorld\": {\n \"Type\": \"Task\",\n \"Resource\":\"arn:aws:lambda:ap-northeast-1:************:function:aws-python-dev-hello\",\n \"End\": true\n }\n }\n}", "name": "TestStateMachine-4VMKMDOODSCT", "roleArn": "arn:aws:iam::************:role/aws-python-dev-InvokeLambdaRole-1P0ARBB2HRIS6", "stateMachineArn": "arn:aws:states:ap-northeast-1:************:stateMachine:TestStateMachine-4VMKMDOODSCT", "creationDate": 1486760475.332 }
- State Machineの実行
$ aws stepfunctions start-execution \ --state-machine-arn "$(aws stepfunctions list-state-machines \ --query 'stateMachines[?name==`TestStateMachine-4VMKMDOODSCT`].stateMachineArn' \ --output text)" \ --input "$(jo hoge=fuga)" { "startDate": 1486762893.681, "executionArn": "arn:aws:states:ap-northeast-1:************:execution:TestStateMachine-4VMKMDOODSCT:d79f8996-07f1-493e-99c1-4a679ce97071" }
- 実行結果が意図したものになったことを確認
$ aws stepfunctions describe-execution \ --execution-arn "arn:aws:states:ap-northeast-1:************:execution:TestStateMachine-4VMKMDOODSCT:d79f8996-07f1-493e-99c1-4a679ce97071" { "status": "SUCCEEDED", "startDate": 1486762893.681, "name": "d79f8996-07f1-493e-99c1-4a679ce97071", "executionArn": "arn:aws:states:ap-northeast-1:************:execution:TestStateMachine-4VMKMDOODSCT:d79f8996-07f1-493e-99c1-4a679ce97071", "stateMachineArn": "arn:aws:states:ap-northeast-1:************:stateMachine:TestStateMachine-4VMKMDOODSCT", "stopDate": 1486762894.946, "output": "{\"body\": \"{\\\"input\\\": {\\\"hoge\\\": \\\"fuga\\\"}, \\\"message\\\": \\\"Go Serverless v1.0! Your function executed successfully!\\\"}\", \"statusCode\": 200}", "input": "{\"hoge\":\"fuga\"}" }
まとめ
いかがだったでしょうか。
CloudFormationがStep Functionsをサポートした点、またServerless Frameworkからこの機能を利用する方法をご紹介しました。 DefinitionString
のYAMLサポート早く来てくれ!!!!1111
本エントリがみなさんの参考になれば幸いに思います。